package org.example.project.common.contant;

import lombok.Builder;
import lombok.Data;
import org.example.project.common.util.ThrowableUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 日志信息体
 *
 * @author wenxy
 * @date 2020/10/26
 */
@Data
@Builder
public class Log implements Serializable {

    private static final long serialVersionUID = -8102992878962304834L;

    String ip;
    String url;
    String signature;
    Object param;
    Object result;
    Throwable exception;
    LocalDateTime createTime;

    @Override
    public String toString() {
        return "Log{" +
                "ip='" + ip + '\'' +
                ", url='" + url + '\'' +
                ", signature='" + signature + '\'' +
                ", param=" + param +
                ", result=" + result +
                ", exception=" + (Objects.isNull(exception) ? "" : ThrowableUtils.getStackTrace(exception)) +
                ", createTime=" + createTime +
                '}';
    }

    /**
     * 简单web请求日志构造器
     * <p>
     * 此方法会有一点性能损耗，如需性能优化可异步处理日志记录，减少影响业务线程
     *
     * @return
     */
    public static Log.LogBuilder simpleLogBuilder() {
        final ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        // web未初始化ok
        if (Objects.isNull(requestAttributes)) {
            return Log.builder();
        }

        final HttpServletRequest request = requestAttributes.getRequest();
        final Log.LogBuilder logBuilder = Log.builder();
        return logBuilder
                .ip(request.getRemoteAddr())
                .url(request.getRequestURL().toString())
                .param(request.getParameterMap().entrySet().stream()
                        .collect(Collectors.toMap(
                                entry -> entry.getKey(),
                                entry -> Arrays.asList(entry.getValue()))))
                .createTime(LocalDateTime.now())
                ;
    }
}